package com.cby.code.net.engine;


import com.cby.code.net.Response;
import com.cby.code.net.listener.ResponseListener;
import com.cby.code.util.HandlerUtils;

import java.lang.ref.WeakReference;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @description: BaseEngine
 * @author: ChenBaoYang
 * @createDate: 2022/2/15 2:21 下午
 */
public abstract class BaseEngine {

    protected WeakReference<ResponseListener> listenerRef;

    /**线程池核心线程数**/
    private static final int CORE_POOL_SIZE = 5;
    /**线程池最大线程数**/
    private static final int MAX_POOL_SIZE = 20;
    /**额外线程空状态生存时间*/
    private static final int KEEP_ALIVE_TIME = 10000;
    /**阻塞队列。当核心线程都被占用，且阻塞队列已满的情况下，才会开启额外线程。**/
    private static final BlockingQueue WORK_QUEUE = new ArrayBlockingQueue(10);
    /**线程池*/
    private static ThreadPoolExecutor threadPool;

    /**
     * 线程工厂
     */
    private static final ThreadFactory THREAD_FACTORY = new ThreadFactory() {
        private final AtomicInteger integer = new AtomicInteger();

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "myThreadPool thread:" + integer.getAndIncrement());
        }
    };

    static {
        threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE,MAX_POOL_SIZE, KEEP_ALIVE_TIME,
                TimeUnit.SECONDS, WORK_QUEUE, THREAD_FACTORY);
    }

    protected void execute(Runnable runnable){
        threadPool.execute(runnable);
    }

    /**
     * 实际执行方法
     */
    public abstract void doWork();

    public void setListener(ResponseListener listener) {
        this.listenerRef = new WeakReference<>(listener);
    }

    protected void handleCallBack(Response response){
        HandlerUtils.runOnMainThread(new Runnable() {
            @Override
            public void run() {
                if(listenerRef != null && listenerRef.get() != null) {
                    listenerRef.get().onResponse(response);
                }
            }
        });
    }
}
